﻿using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;

namespace DefaultNamespace
{
    /// <summary>
    /// 按快捷键F7，高亮选中显示上一个选中的对象，F8切换下一个选中的对象
    /// 缓存下，防止reload重置了数据
    /// </summary>
    [InitializeOnLoad]
    public class SelectionPreviousNextEditor : Editor
    {
        /// <summary>
        /// 最大记录多少步
        /// </summary>
        public const int MaxRecordCount = 20;

        private static List<string> _pathList;
        private static int _currentSelectIndex = -1;

        static SelectionPreviousNextEditor()
        {
            _currentSelectIndex = EditorPrefs.GetInt("currentSelectIndex", -1);
            _pathList = JsonUtility.FromJson<JsonableListWrapper<string>>(EditorPrefs.GetString("pathList")).list;
            if (_pathList == null)
            {
                _pathList = new List<string>(MaxRecordCount);
                _currentSelectIndex = -1;
            }
            else
            {
                var newList = new List<string>(MaxRecordCount);
                //如果换项目了，需要在加载时候清空不存在的路径
                foreach (var filePath in _pathList)
                {
                    if (File.Exists(filePath))
                    {
                        newList.Add(filePath);
                    }
                }

                _pathList = newList;
            }

            if (_currentSelectIndex > _pathList.Count - 1)
            {
                _currentSelectIndex = _pathList.Count - 1;
            }

            // Debug.Log(
            //     $"从缓存:{_currentSelectIndex},获取到了{_pathList.Count}条数据");

            EditorApplication.projectWindowItemOnGUI += OnProjectWindowItemGUI;
        }

        private static void OnProjectWindowItemGUI(string guid, Rect selectionRect)
        {
            if (Event.current.type == EventType.MouseDown && Event.current.button == 0 &&
                selectionRect.Contains(Event.current.mousePosition))
            {
                string selectedPath =
                    AssetDatabase.GUIDToAssetPath(guid);

                //只记录文件而不记录目录
                if (!AssetDatabase.IsValidFolder(selectedPath))
                {
                    _pathList.Add(selectedPath);
                    if (_pathList.Count > MaxRecordCount)
                    {
                        _pathList.RemoveAt(0);
                    }

                    _currentSelectIndex = _pathList.Count - 1;
                    EditorPrefs.SetInt("currentSelectIndex", _currentSelectIndex);
                    EditorPrefs.SetString("pathList", JsonUtility.ToJson(new JsonableListWrapper<string>(_pathList)));
                }
            }
        }


        [MenuItem("快捷键/选中上次选中的对象 _F7")]
        private static void SelectPrevious()
        {
            if (_currentSelectIndex <= 0)
            {
                return;
            }

            _currentSelectIndex--;


            Object selectPrevious =
                AssetDatabase.LoadAssetAtPath(_pathList[_currentSelectIndex], typeof(UnityEngine.Object));
            if (selectPrevious != null)
            {
                //选择一个对象，使其在Hierarchy面板中高亮显示
                // Selection.activeObject = selectPrevious;
                //在Project面板中定位并突出显示指定的对象
                EditorGUIUtility.PingObject(selectPrevious);
                return;
            }
            else
            {
                _currentSelectIndex++;
            }

            EditorPrefs.SetInt("currentSelectIndex", _currentSelectIndex);
        }

        [MenuItem("快捷键/选中下一个对象 _F8")]
        private static void SelectNext()
        {
            if (_currentSelectIndex >= _pathList.Count - 1)
            {
                return;
            }

            _currentSelectIndex++;
            Object selectPrevious =
                AssetDatabase.LoadAssetAtPath(_pathList[_currentSelectIndex], typeof(UnityEngine.Object));
            if (selectPrevious != null)
            {
                // Selection.activeObject = selectPrevious;
                EditorGUIUtility.PingObject(selectPrevious);
            }
            else
            {
                _currentSelectIndex--;
            }

            EditorPrefs.SetInt("currentSelectIndex", _currentSelectIndex);
        }


        [MenuItem("快捷键/选中上次选中的对象 _F7", true)]
        private static bool ValidateSelectPrevious()
        {
            return _pathList.Count > 1;
        }

        [MenuItem("快捷键/选中下一个对象 _F8", true)]
        private static bool ValidateSelectNext()
        {
            return _pathList.Count > 1;
        }
    }

    [System.Serializable]
    public class JsonableListWrapper<T>
    {
        //Unity自带的Json序列化不支持List<string>这种，所以菜用这种蠢办法
        public List<T> list;
        public JsonableListWrapper(List<T> list) => this.list = list;
    }
}